﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Diagnostics;

namespace _1945
{
    public class Enemy : GameObject
    {
        int health;
        int maxHealth;
        bool showHealthBar;
        int bulletsPerSecond;
        bool movementHoming; //is not working right now due to movementpattern...
        bool isBoss;
        public bool IsBoss { get { return isBoss; } }
        public int Score { get { return score; } }

        int bulletDamage;
        public int BulletDamage { get { return bulletDamage; } }
        List<GameObject> bullets;
        Sprite bullet;

        Vector2 enemyCannonPosition = Vector2.Zero;

        TimeSpan fireDelay = new TimeSpan();
        TimeSpan lastFire = new TimeSpan();

        TimeSpan homingMovementDelay = new TimeSpan(0, 0, 0, 0, 500);
        TimeSpan lastHomingMovement = new TimeSpan();

        MovementPattern movementPattern;

        Random rand = new Random((int)DateTime.Now.Ticks);

        public Enemy(Game game, Texture2D gameSpriteSheet, bool isBoss, int score, int health, bool showHealthBar, Vector2 startpos, Vector2 speed, int bulletsPerSecond, bool homing, int bulletDamage, Sprite sprite, Rectangle gameScreenBounds, Sprite bullet, List<GameObject> bullets, MovementPattern movementPattern)
            : base(game, gameSpriteSheet, startpos, speed, Vector2.Zero, sprite, gameScreenBounds)
        {
            this.isBoss = isBoss;
            this.score = score;
            this.health = health;
            maxHealth = health;
            this.showHealthBar = showHealthBar;
            this.bulletsPerSecond = bulletsPerSecond;
            fireDelay = new TimeSpan(10000000 / bulletsPerSecond);
            this.movementHoming = homing;
            this.bullets = bullets;
            this.bullet = bullet;
            this.movementPattern = movementPattern;
        }


        //Where playerBullets should fire from
        private void setEnemyCannonPosition()
        {
            enemyCannonPosition.X = position.X + sprite.getWidth() / 2 - bullet.getWidth() / 2;
            enemyCannonPosition.Y = position.Y + sprite.getHeight();
        }

        private void fireBullet(GameTime gameTime, Vector2 playerPosition, int playerWidth)
        {

            //Debug.Print("ENEMY elapsed GT: " + gameTime.TotalGameTime.ToString() + " lastfire: " + lastFire.ToString() + " elapsed-lastfire: " + gameTime.TotalGameTime.Subtract(lastFire).ToString());
            if (gameTime.TotalGameTime.Subtract(lastFire).CompareTo(fireDelay) > 0)
            {
                if (!isBoss)
                {
                    if (rand.Next(1, 100) == 2)
                    {
                        Vector2 homingBulletPath = playerPosition - enemyCannonPosition;
                        homingBulletPath.Normalize();
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(3), homingBulletPath, bullet, gameScreenBounds));
                        lastFire = gameTime.TotalGameTime;
                    }
                    else
                    {
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(5), new Vector2(0, 1), bullet, gameScreenBounds));
                        lastFire = gameTime.TotalGameTime;
                    }
                }
                else
                {
                    //playerPosition
                    playerPosition.X += playerWidth / 2;
                    playerPosition.Y += playerWidth / 2;
                    Vector2 homingBulletPath = playerPosition - enemyCannonPosition;
                    homingBulletPath.Normalize();

                    if (rand.Next(1, 11) == 5)
                    {
                        //fire in star scheme
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(4), new Vector2(1, 0), bullet, gameScreenBounds));
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(4), new Vector2(-1, 0), bullet, gameScreenBounds));
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(4), new Vector2(0, 1), bullet, gameScreenBounds));
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(4), new Vector2(0, -1), bullet, gameScreenBounds));
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(4), new Vector2(1, 1), bullet, gameScreenBounds));
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(4), new Vector2(1, -1), bullet, gameScreenBounds));
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(4), new Vector2(-1, 1), bullet, gameScreenBounds));
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(4), new Vector2(-1, -1), bullet, gameScreenBounds));
                    }
                    else
                    {
                        //homing fire
                        bullets.Add(new GameObject(Game, gameSpriteSheet, enemyCannonPosition, new Vector2(5), homingBulletPath, bullet, gameScreenBounds));
                    }
                    lastFire = gameTime.TotalGameTime;
                }
            }

        }

        public void damage(int hitPoints, GameTime gameTime)
        {
            health -= hitPoints;

            if (health <= 0)
            {
                this.explode(gameTime);
            }
        }

        /// <summary>
        /// Returns a clone (deepcopy) of the current object
        /// </summary>
        /// <returns></returns>
        public Enemy clone()
        {
            return new Enemy(Game, gameSpriteSheet, isBoss, score, health, showHealthBar, startPos, speed, bulletsPerSecond, movementHoming, bulletDamage, sprite, gameScreenBounds, bullet, bullets, movementPattern);
        }

        public void Update(GameTime gameTime, Vector2 playerPosition, int playerWidth)
        {
            setEnemyCannonPosition();

            if (!isExploding)
            {
                if (movementHoming && gameTime.TotalGameTime.Subtract(lastHomingMovement).CompareTo(homingMovementDelay) > 0)
                {

                    if (enemyCannonPosition.X > playerPosition.X && enemyCannonPosition.X < playerPosition.X + playerWidth)
                    {
                        direction.X = 0;
                    }
                    else if (enemyCannonPosition.X > playerPosition.X + playerWidth && position.Y < playerPosition.Y )
                    {
                        direction.X = -1;
                    }
                    else if (enemyCannonPosition.X < playerPosition.X && position.Y < playerPosition.Y)
                    {
                        direction.X = 1;
                    }

                    lastHomingMovement = gameTime.TotalGameTime;
                }

                //move enemies onscreen
                if (direction.Y != 1 && position.Y < 0)
                {
                    position.Y++;
                }
                /*
                 * homing movement has no meaning right now...
                 */ 
                direction = movementPattern.getDirection(position, speed, gameTime.TotalGameTime);
                fireBullet(gameTime, playerPosition, playerWidth);
            }

            base.Update(gameTime);

        }

        public override void Draw(GameTime gameTime)
        {
            //health bar
            if (showHealthBar)
            {
                spriteBatch.Draw(blackTexture, new Vector2(gameScreenBounds.Width - 120, 30), new Rectangle(100, 101, 100, 20), new Color(255, 255, 255, 50));
                spriteBatch.Draw(blackTexture, new Vector2(gameScreenBounds.Width - 120, 30), new Rectangle(100, 101, 100 * health/maxHealth, 20), Color.GreenYellow);
                spriteBatch.DrawString(spriteFont, "Enemy", new Vector2(gameScreenBounds.Width - 190, 28), Color.White);
            
            }
            if (isBoss)
            {
                spriteBatch.Draw(gameSpriteSheet, new Vector2((int)position.X, (int)position.Y), sprite.getSpriteRectangle(), Color.White, 0, Vector2.Zero, 1, SpriteEffects.FlipVertically,0);
            }
            else
            {
                base.Draw(gameTime);
            }
            
        }
    }
}
